LLM Agent 如何进行动态 API 调用?
动态 API 调用指:Agent 在运行时根据任务,从 API 目录 / OpenAPI 契约里选出接口并填参执行,而不是开发期把每个 HTTP 端点硬编码成固定 Tool。本篇讲面试答法;静态工具注册见 工具调用与评测实践;跨进程工具交付见 MCP 概览与实践。
静态 vs 动态
| 维度 | 静态工具(预注册) | 动态 API 调用 |
|---|---|---|
| schema 来源 | 代码里手写 name / description / JSON schema | OpenAPI / Postman / API 网关 等契约解析 |
| 工具面 | 固定、可控 | 随接入 API 数量增长,需裁剪 |
| 典型场景 | 核心业务、强耦合、低延迟 | SaaS 集成、客户自带 API、开放平台 |
| 风险 | 改 API 要发版 | schema 漂移、鉴权复杂、选错接口 |
面试先一句话:动态 = 把「HTTP 契约 → function calling schema → 受控执行」流水线自动化。
标准闭环
用户目标
↓
(可选)从 API 目录检索相关端点 ──→ 裁剪本次可用 tool list
↓
LLM 输出:endpoint + method + path/query/body 参数
↓
执行层:校验 schema → 注入鉴权 → 发 HTTP → 超时/重试
↓
响应解析(截断/结构化)→ 塞回上下文 → ReAct 继续或结束
和 Agent 核心概念与架构 里的 感知-规划-行动 循环一致:工具执行结果就是「观察」。
关键模块
1. API 发现与 schema 转换
| 输入 | 产出 |
|---|---|
| OpenAPI 3.x / Swagger | 每个 operation → 一个 tool:name、description、parameters(JSON Schema) |
| API 网关导出、内部 API Catalog | 同上,可加业务标签、权限域 |
转换要点:
operationId或method + path作稳定 tool namesummary/description给模型读——描述质量决定选型准确率- 必填参数、枚举、格式(
date-time、uuid)写进 schema - 大 spec 按 tag / 服务 / 租户 分片,不要一次塞几百个 tool
2. 工具面裁剪(Tool Routing)
API 一多,全量塞进 Prompt 会:超上下文、选错、成本高。
| 策略 | 做法 |
|---|---|
| 检索式 | 把 operation 描述 embedding,按用户 query Top-K 召回 |
| 规则式 | 按租户已开通产品、OAuth scope、场景标签过滤 |
| 两阶段 | 小模型 / 分类器先选「服务域」,再在域内 function calling |
| 元工具 | 暴露 search_apis + call_api,让 Agent 先搜再调(步数换精度) |
3. 执行器(HTTP Executor)
def call_api(operation: dict, args: dict, auth_ctx) -> dict:
# 1. JSON Schema 校验 args
validate(args, operation["requestSchema"])
# 2. 拼 URL(path 参数替换)、query、body
req = build_request(operation, args)
# 3. 注入鉴权:Bearer / API Key / OAuth token(从 auth_ctx,勿让模型填密钥)
req.headers["Authorization"] = auth_ctx.token_for(operation["service"])
# 4. 超时、有限重试、响应大小上限
resp = http_client.request(req, timeout=30, max_bytes=64_000)
return truncate_json(resp)
生产必谈:
- 鉴权与密钥:模型只填业务参数;token 由 Host 按用户身份注入
- SSRF / 内网:允许列表域名、禁止私有 IP、或走企业 API 代理
- 幂等与副作用:POST 写操作要人审或 idempotency key
- 错误分类:4xx 参数错 → 改参重试;5xx / 超时 → 有限重试;401 → 刷新 token 或降级
4. 结果回灌
- 长 JSON:截断 + 摘要,或 jq 式抽取字段再进上下文
- 失败时把 HTTP status + 错误体 结构化给模型,便于改参
- 全链路 轨迹日志(选了哪个 API、参数、耗时)——见 工具调用与评测实践
与 MCP / Function Calling 的关系
| 机制 | 角色 |
|---|---|
| Function / Tool Calling | 模型「选哪个 tool + 填 JSON 参数」的接口格式 |
| 动态 OpenAPI 流水线 | 把外部 HTTP 变成 tool list 的工程方式 |
| MCP | 工具以 Server 形式跨进程交付;Server 内部可以是 OpenAPI 执行器 |
不冲突:常见组合是 MCP Server 封装「动态调 OpenAPI」,Host 仍用 function calling 选 MCP tool。
常见坑
| 坑 | 表现 | 缓解 |
|---|---|---|
| schema 与真实 API 不一致 | 调通率低 | 契约测试、版本化 spec、灰度 |
| 工具过多 | 幻觉选型 | 检索 Top-K、分域、元工具两阶段 |
| 模型编造 path / 参数 | 404 / 422 | 强校验、只允许 catalog 内 operationId |
| 敏感数据进日志 | 合规事故 | 参数脱敏、响应字段白名单 |
| 无限 ReAct | 成本爆炸 | 最大步数、墙钟超时、重复调用检测 |
面试参考答法(60~90 秒)
Agent 动态调 API,核心是三条线:契约转 tool schema、运行时裁剪工具面、受控 HTTP 执行。
开发期或接入期把 OpenAPI 解析成 function 定义;请求进来先用检索或规则从几百个接口里筛出 Top-K 相关工具,再让 LLM 做 function calling 选 endpoint 和参数。执行层做 schema 校验、从会话注入 OAuth/API Key、设超时和响应上限,把结果结构化塞回上下文继续 ReAct。
和静态手写 tool 比,动态适合客户自带 API、开放平台;代价是要做 tool routing、鉴权隔离和契约同步。Function calling 是模型侧机制,MCP 可以是交付层,OpenAPI 执行器可以跑在 MCP Server 里。
延伸阅读
| 篇 | 关系 |
|---|---|
| Agent 系统高频题 | 工具调用 / ReAct 速答 |
| MCP 概览与实践 | 跨进程工具标准 |
| API 设计与 HTTP 实践 | REST / OpenAPI 契约基础 |
面试速记
- 动态 vs 静态: 契约驱动、运行时选接口;静态适合窄而深的业务 tool。
- 四段流水线: 发现与转 schema → 裁剪 tool 面 → LLM 填参 → 受控 HTTP 执行与回灌。
- Tool Routing: API 多时必须检索 Top-K / 分域 / 两阶段,不能全量塞 Prompt。
- 执行层底线: 鉴权由 Host 注入、参数 schema 校验、超时重试、SSRF 与日志脱敏。
- 和 MCP: function calling 是选型机制;MCP 是交付方式;OpenAPI 执行器常包在 Server 里。